import re
from saip.usuario.models import Usuario, Rol, Permiso
from django import forms
from django.contrib.auth import authenticate
from django.utils.translation import ugettext_lazy as _
from django.contrib.admin.widgets import FilteredSelectMultiple

"""
Formularios para el manejo del modulo de administracion del sistema.
:author: Marco Rolon, Bianca Benegas
"""

class RegistrationForm(forms.Form):
    """
    Clase que genera el formulario para registrar un nuevo usuario.
    """
    username = forms.CharField(label=u'Username', max_length=30)
    password1 = forms.CharField(
        label=u'Contrase\xf1a',
        widget=forms.PasswordInput()
    )
    password2 = forms.CharField(
        label=u'Contrase\xf1a (De nuevo)',
        widget=forms.PasswordInput()
    )
    nombre = forms.CharField(label=u'Nombre', max_length=30, required=False)
    apellido = forms.CharField(label=u'Apellido', max_length=30, required=False)
    email = forms.EmailField(label=u'Email', required=False)
    direccion = forms.CharField(label=u'Direcci\xf3n', max_length=100, required=False)
    telefono = forms.CharField(label=u'Tel\xe9fono', max_length=15, required=False)
    def clean_password2(self):
        """
        Comprueba que la contrasenha ingresada sea correcta.
        """
        if 'password1' in self.cleaned_data:
            password1 = self.cleaned_data['password1']
            password2 = self.cleaned_data['password2']
            if password1 == password2:
                return password2
            raise forms.ValidationError('Passwords no coinciden')
			
    def clean_username(self):
        """
        Verifica si el username fue ingresado con el formato correcto.
        """
        username = self.cleaned_data['username']
        if not re.search(r'^\w+$', username):
            raise forms.ValidationError('Username solo puede tener caract\xe9res alfanum\xe9ricos.')
        try:
            Usuario.objects.get(username=username)
        except Usuario.DoesNotExist:
            return username
        raise forms.ValidationError('Ya hay un usuario con ese nombre.')
    def clean_telefono(self):
        """
        Verifica si el telefono fue ingresado con el formato correcto.
        """
        telefono = self.cleaned_data['telefono']
        if not re.search(r'^\d*$', telefono):
            raise forms.ValidationError(u'Tel\xe9fono solo puede tener caract\xe9res num\xe9ricos.')
        return telefono


class UsuarioEditForm(forms.Form):
    """
    Clase que genera el formulario para la edicion del registro de usuario.
    """
    username = forms.CharField(label=u'Username', max_length=30)
    nombre = forms.CharField(label=u'Nombre', max_length=30, required=False)
    apellido = forms.CharField(label=u'Apellido', max_length=30, required=False)
    email = forms.EmailField(label=u'Email', required=False)
    direccion = forms.CharField(label=u'Direcci\xf3n', max_length=100, required=False)
    telefono = forms.CharField(label=u'Tel\xe9fono', max_length=15, required=False)
    iduser = forms.IntegerField(widget=forms.HiddenInput(attrs={'size': 12}), required=False)
    def clean_username(self):
        """
        Verifica si el username fue ingresado con el formato correcto.
        """
        username = self.cleaned_data['username']
        iduser = self.data['iduser']
        if not re.search(r'^\w+$', username):
            raise forms.ValidationError('Username solo puede tener caract\xe9res alfanum\xe9ricos.')
        try:
            useruno = Usuario.objects.get(username=username)
            userdos = Usuario.objects.get(id=iduser)
            if useruno.nombre==userdos.nombre:
                return username
        except Usuario.DoesNotExist:
            return username
        raise forms.ValidationError('Ya hay un usuario con ese nombre.')
    def clean_telefono(self):
        """
        Verifica si el telefono fue ingresado con el formato correcto.
        """
        telefono = self.cleaned_data['telefono']
        if not re.search(r'^\d*$', telefono):
            raise forms.ValidationError(u'Tel\xe9fono solo puede tener caracteres num\xe9ricos.')
        return telefono
    
class UAuthenticationForm(forms.Form):
    """
    Clase base para autenticar a los usuarios. Amplie esto para conseguir una 
    forma que acepta nombre de usuario / contrasenha de inicio de sesion.
    Base class for authenticating users. Extend this to get a form that accepts
    username/password logins.
    """
    username = forms.CharField(label=u'Username', max_length=30)
    password = forms.CharField(label=u'Password', widget=forms.PasswordInput)

    def __init__(self, request=None, *args, **kwargs):
        """
        If request is passed in, the form will validate that cookies are
        enabled. Note that the request (a HttpRequest object) must have set a
        cookie with the key TEST_COOKIE_NAME and value TEST_COOKIE_VALUE before
        running this validation.
        """
        self.request = request
        self.user_cache = None
        super(AuthenticationForm, self).__init__(*args, **kwargs)

    def clean(self):
        username = self.cleaned_data.get('username')
        password = self.cleaned_data.get('password')

        if username and password:
            self.user_cache = authenticate(username=username, password=password)
            if self.user_cache is None:
                raise forms.ValidationError(_("Please enter a correct username and password. Note that both fields are case-sensitive."))
            elif not self.user_cache.is_active:
                raise forms.ValidationError(_("This account is inactive."))

        # TODO: determine whether this should move to its own method.
        if self.request:
            if not self.request.session.test_cookie_worked():
                raise forms.ValidationError(_("Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in."))

        return self.cleaned_data

    def get_user_id(self):
        if self.user_cache:
            return self.user_cache.id
        return None

    def get_user(self):
        return self.user_cache

class ChangePassForm(forms.Form):
    """
    Clase que genera el formulario para el cambio de contrasenha.
    """
    username = forms.CharField(label=u'Nombre de usuario', max_length=30, widget=forms.HiddenInput())
    password = forms.CharField(label=u'Contrase\xf1a', widget=forms.PasswordInput())
    password1 = forms.CharField(label=u'Nueva Contrase\xf1a', widget=forms.PasswordInput())
    password2 = forms.CharField(label=u'Confirmar Contrase\xf1a', widget=forms.PasswordInput())

    def clean_password(self):
        """
        Verifica que la contrasenha sea correcta.
        """
        if 'password' in self.cleaned_data:
            user = Usuario.objects.get(username=self.cleaned_data['username'])
            password = self.cleaned_data['password']
            if user.check_password(password):
                return password
        raise forms.ValidationError(u'La Contrase\xf1a no es valida')

    def clean_password2(self):
        """
        Comprueba que la contrasenha nueva ingresada sea correcta.
        """
        if 'password1' in self.cleaned_data:
            password1 = self.cleaned_data['password1']
            password2 = self.cleaned_data['password2']
            if password1 == password2:
                return password2
        raise forms.ValidationError(u'Las Contrase\xf1as no coinciden')

class RolForm(forms.Form):
    """
    Clase que genera el formulario para registrar un nuevo rol.
    """
    nombre = forms.CharField(label=u'Nombre', widget=forms.TextInput(attrs={'size': 64}))
    descripcion = forms.CharField(label=u'Descripci\xf3n', widget=forms.Textarea(attrs={'rows':3, 'cols':60}), max_length=200)
    permisos = forms.ModelMultipleChoiceField(queryset=Permiso.objects.all(), widget=forms.CheckboxSelectMultiple(), required=False)
		
class RolAdmForm(forms.Form):
    """
    Clase que genera el formulario para registrar un Rol Administrativo.
    """
    nombre = forms.CharField(label=u'Nombre', widget=forms.TextInput(attrs={'size': 64}))
    descripcion = forms.CharField(label=u'Descripci\xf3n', widget=forms.Textarea(attrs={'rows':3, 'cols':60}), max_length=200)
    permisos = forms.ModelMultipleChoiceField(queryset=Permiso.objects.filter(tipo='A').exclude(id=1), widget=forms.CheckboxSelectMultiple(), required=False)
    #permisos = forms.ModelMultipleChoiceField(queryset=Permiso.objects.filter(tipo='A').exclude(id=1), widget=FilteredSelectMultiple("verbose name", is_stacked=False), required=False)
    
	
class RolOpForm(forms.Form):
    """
    Clase que genera el formulario para registrar un Rol Operativo.
    """
    nombre = forms.CharField(label=u'Nombre', widget=forms.TextInput(attrs={'size': 64}))
    descripcion = forms.CharField(label=u'Descripci\xf3n', widget=forms.Textarea(attrs={'rows':3, 'cols':60}), max_length=200)
    permisos = forms.ModelMultipleChoiceField(queryset=Permiso.objects.filter(tipo='O'), widget=forms.CheckboxSelectMultiple(), required=False)

class RolEditForm(forms.Form):
    """
    Clase que genera el formulario para la edicion del registro de un rol.
    """
    nombre = forms.CharField(label=u'Nombre', widget=forms.TextInput(attrs={'size': 64}))
    descripcion = forms.CharField(label=u'Descripci\xf3n', widget=forms.Textarea(attrs={'rows':3, 'cols':60}), max_length=200)
    permisos = forms.ModelMultipleChoiceField(queryset=Permiso.objects.all(), widget=forms.CheckboxSelectMultiple(), required=False)

class PermisoForm(forms.Form):
    """
    Clase que genera el formulario para registrar un nuevo permiso.
    """
    nombre = forms.CharField(label=u'Nombre', widget=forms.TextInput(attrs={'size': 64}))
    descripcion = forms.CharField(label=u'Descripci\xf3n', widget=forms.Textarea(attrs={'rows':3, 'cols':60}), max_length=200)
	
class PermisoEditForm(forms.Form):
    """
    Clase que genera el formulario para la edicion del registro de un permiso.
    """
    nombre = forms.CharField(label=u'Nombre', widget=forms.TextInput(attrs={'size': 64}))
    descripcion = forms.CharField(label=u'Descripci\xf3n', widget=forms.Textarea(attrs={'rows':3, 'cols':60}), max_length=200)

class RolAsAdForm(forms.Form):
    """
    Clase que genera el formulario para asignar un Rol Administrativo.
    """
    #nombre = forms.CharField(label=u'Nombre', widget=forms.TextInput(attrs={'size': 64}))
    roladm = forms.ModelMultipleChoiceField(queryset=Rol.objects.filter(tipo='A').exclude(id=1), widget=forms.CheckboxSelectMultiple(), required=False)

class SearchForm(forms.Form):
    buscar = forms.CharField(widget=forms.TextInput(attrs={'size': 32}))